asp.net 核心 2.0 授权在身份验证 (JWT) 之前触发
asp.net core 2.0 Authorization is firing before authentication (JWT)
我正在尝试在我的 asp.net 核心 2.0 应用程序中实施自定义授权策略。
在我的 Custom AuthorizationHandler 中我有这个检查:
if (!context.User.Identity.IsAuthenticated)
{
this.logger.LogInformation("Failed to authorize user. User is not authenticated.");
return Task.CompletedTask;
}
// ... More authorization checks
这是有道理的,因为未经身份验证的用户无权执行我的控制器操作。
我正在使用 JWT 承载身份验证并将其配置如下:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = "<issuer>",
ValidAudience = "<audience>",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signingKey)),
ValidateLifetime = false
};
});
我也在注册我的授权要求和处理程序(请注意,这些注册发生在我在上面配置身份验证之后,并且在我调用 serivces.AddMVC()
:
之前
services.AddAuthorization(options =>
{
options.AddPolicy(Constants.AuthorizationPolicies.MyCustomPolicy,
policy => policy.Requirements.Add(new MyCustomRequirement()));
});
services.AddScoped<IAuthorizationHandler, MyCustomAuthorizationHandler>();
这是我的问题,我的授权策略似乎在 jwt 令牌受到挑战和验证之前正在执行,因此,我的授权策略失败了,因为用户未通过身份验证。
这是一个示例调用的日志:
Now listening on: http://localhost:60235
Application started. Press Ctrl+C to shut down.
[14:50:57 INF] Request starting HTTP/1.1 GET http://localhost:60235/api/values application/json
[14:51:03 INF] Failed to authorize user. User is not authenticated.
[14:51:03 INF] Authorization failed for user: null.
[14:51:03 INF] Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
[14:51:03 INF] Executing ChallengeResult with authentication schemes ([]).
[14:51:03 INF] Successfully validated the token.
[14:51:03 INF] AuthenticationScheme: Bearer was challenged.
[14:51:03 INF] Executed action AuthorizationTestClient.Controllers.ValuesController.Get (AuthorizationTestClient) in 5819.1586ms
[14:51:03 INF] Request finished in 5961.5619ms 401
如您所见,授权策略首先执行,由于用户未通过身份验证而失败,然后发生身份验证质询。
这不应该反过来吗?如何让asp.net在授权前进行认证?
I'm also registering my authorization requirement and handler (note
these registrations happen AFTER I've configured authentication above,
and BEFORE I call serivces.AddMVC()
服务在 DI 容器中的注册顺序不是很重要。 重要的是 Startup.Configure
方法中中间件注册的顺序。你没有提供这个方法的代码,但我打赌你在 MVC 中间件之后添加身份验证中间件或者根本不添加它。身份验证中间件应在 MVC 之前添加,因此请确保您的 Startup.Configure
看起来类似于:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
查看以下文章了解更多详情:
好的..事实证明这很容易修复。我需要在我的 Configure 方法中调用 app.UseAuthentication() 。傻我!
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
我正在尝试在我的 asp.net 核心 2.0 应用程序中实施自定义授权策略。
在我的 Custom AuthorizationHandler 中我有这个检查:
if (!context.User.Identity.IsAuthenticated)
{
this.logger.LogInformation("Failed to authorize user. User is not authenticated.");
return Task.CompletedTask;
}
// ... More authorization checks
这是有道理的,因为未经身份验证的用户无权执行我的控制器操作。
我正在使用 JWT 承载身份验证并将其配置如下:
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.SaveToken = true;
cfg.TokenValidationParameters = new TokenValidationParameters
{
ValidIssuer = "<issuer>",
ValidAudience = "<audience>",
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(signingKey)),
ValidateLifetime = false
};
});
我也在注册我的授权要求和处理程序(请注意,这些注册发生在我在上面配置身份验证之后,并且在我调用 serivces.AddMVC()
:
services.AddAuthorization(options =>
{
options.AddPolicy(Constants.AuthorizationPolicies.MyCustomPolicy,
policy => policy.Requirements.Add(new MyCustomRequirement()));
});
services.AddScoped<IAuthorizationHandler, MyCustomAuthorizationHandler>();
这是我的问题,我的授权策略似乎在 jwt 令牌受到挑战和验证之前正在执行,因此,我的授权策略失败了,因为用户未通过身份验证。
这是一个示例调用的日志:
Now listening on: http://localhost:60235
Application started. Press Ctrl+C to shut down.
[14:50:57 INF] Request starting HTTP/1.1 GET http://localhost:60235/api/values application/json
[14:51:03 INF] Failed to authorize user. User is not authenticated.
[14:51:03 INF] Authorization failed for user: null.
[14:51:03 INF] Authorization failed for the request at filter 'Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter'.
[14:51:03 INF] Executing ChallengeResult with authentication schemes ([]).
[14:51:03 INF] Successfully validated the token.
[14:51:03 INF] AuthenticationScheme: Bearer was challenged.
[14:51:03 INF] Executed action AuthorizationTestClient.Controllers.ValuesController.Get (AuthorizationTestClient) in 5819.1586ms
[14:51:03 INF] Request finished in 5961.5619ms 401
如您所见,授权策略首先执行,由于用户未通过身份验证而失败,然后发生身份验证质询。
这不应该反过来吗?如何让asp.net在授权前进行认证?
I'm also registering my authorization requirement and handler (note these registrations happen AFTER I've configured authentication above, and BEFORE I call serivces.AddMVC()
服务在 DI 容器中的注册顺序不是很重要。 重要的是 Startup.Configure
方法中中间件注册的顺序。你没有提供这个方法的代码,但我打赌你在 MVC 中间件之后添加身份验证中间件或者根本不添加它。身份验证中间件应在 MVC 之前添加,因此请确保您的 Startup.Configure
看起来类似于:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}
查看以下文章了解更多详情:
好的..事实证明这很容易修复。我需要在我的 Configure 方法中调用 app.UseAuthentication() 。傻我!
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseAuthentication();
app.UseMvc();
}